import getopt
import re
import logging
from google.appengine.api import xmpp
from google.appengine.ext import webapp 
from google.appengine.ext import db 
from google.appengine.ext.webapp import xmpp_handlers 
from google.appengine.ext.webapp.util import run_wsgi_app

class User(db.Model):
  mail = db.StringProperty()
  type = db.StringProperty(choices=set(["weather","xiaonei"]))
  user = db.StringProperty()
  password = db.StringProperty()
  data = db.StringProperty(multiline=True)

class Weather(db.Model):
  city = db.StringProperty()
  data = db.TextProperty()

def get_command(sender, arg):
  args = arg.split()
  mail = re.search('(.*)/?.*',sender).group(1)
  t = u = p = d = ""
  failed = False
  try:
    optlist, args=getopt.getopt(args, 'u:p:t:')
    text = ""
    for opt, val in optlist:
      if opt == '-u':
        u = val
      elif opt == '-p':
        p = val
      elif opt == '-t':
        if val in ("xiaonei", "weather"):
          t = val
        else:
          text += "type %s not support" % val
          failed = True
  except getopt.GetoptError, err:
    logging.info("GTalk command error from %s: %s" % (sender, str(err)))
    d = str(err)
  return (mail, t.lower(), u, p, d)

class XMPPHandler(xmpp_handlers.CommandHandler):
  def text_message(self, message=None):
    message.reply(message.sender + message.to + message.body)

  def delete_command(self, message=None):
    #/d -t type -u user
    (mail, type, user, password, data) = get_command(message.sender, message.arg)
    if(data != ""):
      message.reply(data)
      return
    res = db.GqlQuery("select * from User where mail=:1 and type=:2 and user=:3" , mail, type, user)
    if(res.count() > 0):
      db.delete(res)
      message.reply("Account %s in %s deleted." % (user, type))
      #check if others have the same weather city
      if (type == 'weather'):
        res = db.GqlQuery("select * from User where user=:1", user)
        if (res.count() <= 0):
          res = db.GqlQuery("select * from Weather where city=:1", user)
          if (res.count() > 0):
            db.delete(res)
            logging.info("City %s deleted by %s" %(user, mail))
    else:
      message.reply("No record found in %s." % type)
  
  def d_command(self, message=None):
    self.delete_command(message)

  def bind_command(self, message=None):
    #/b -t type -u user -p password
    (mail, type, user, password, data) = get_command(message.sender, message.arg)
    if (data!= ""):
      message.reply(data)
      return
    res = db.GqlQuery("select * from User where mail = :1 and type = :2", mail, type) 
    old_user = ""
    if(res.count()>0):
      record = res.get()
      old_user = record.user
      record.user = user
      record.password = password
      record.put()
      message.reply("%s in %s updated" % (user, type))
    else:
      new_record= User(mail=mail, type=type, user=user, password=password, data="")
      new_record.put()
      message.reply("%s in %s added" % (user, type))
    if (type=="weather"):
      #update weather DB
      res = db.GqlQuery("select * from Weather where city = :1", old_user)
      if(res.count() == 1):
        db.delete(res)
        logging.info("City %s deleted by %s" %(old_user, mail))
      res = db.GqlQuery("select * from Weather where city = :1", user)
      if(res.count() <= 0):
        weather = Weather(city=user, data="No weather info now.")
        weather.put()
        logging.info("City %s added by %s" % (user, mail))
    
  def b_command(self, message=None):
    self.bind_command(message)

  def help_command(self, message=None):
    message.reply("/h: help\n /b accont passwords")

  def h_command(self, message=None):
    self.help_command(message)
 
  def unhandled_command(self, message=None):
    self.help_command(message)


def main():
  logging.getLogger().setLevel(logging.DEBUG)
  application = webapp.WSGIApplication(
      [('/_ah/xmpp/message/chat/', XMPPHandler)],
      debug=True)
  run_wsgi_app(application)

if __name__ == "__main__":
  main();
